<?php
abstract class MA {

	var $error;
	var $index;
	var $dom,$xp,$timeinfo;

	function getData($source,$timeperiods,$report,$obs,$type,$view,$filter,$sort,$rowlimit,$arguments) {
		if($ret=$this->checkTimeperiods($source,$timeperiods)) {
			throw new Exception("Time resolution not supported: $ret");
			return;
		}			
		
		if(count($obs)==0) {
			$tmp=$this->getObspoints($source);
			foreach($tmp as $t)
				$obs[]=$t['id'];
		}
		
		if($type=="singleTable" or $type=="table")
			return $this->getTableOrSingleData($source,$timeperiods,$report,$obs,$type,$view,$filter,$sort,$rowlimit,$arguments);
			
		if($type=="singleOverview")
			return $this->getSingleOverview($source,$timeperiods,$report,$obs,$type,$view,$filter,$sort,$rowlimit,$arguments);
	}
	
	private function checkTimeperiods($source,$timeperiods) {
		if(!isset($this->timeinfo[$source]))
			$this->timeinfo[$source]=$this->getTimeinfo($source);
		foreach($timeperiods as $t) {
			foreach($this->timeinfo[$source] as $info)
				if($t['resolution']==$info['duration'])
					return 0;
			return $t['resolution'];
		}
	}
	
	function getSingleOverview($source,$timeperiods,$report,$obs,$type,$view,$filter,$sort,$rowlimit,$arguments) {
		$data=$this->getTableOrSingleData($source,$timeperiods,$report,$obs,"singleTable",$view,$filter,$sort,0,$arguments);
		$ret=array();
		foreach($data as $tid=>$obs) {
			$tmp=array();
			$row=0;
			foreach($obs as $oid=>$rows) {
				$tmp[$row]=array();				
				$tmp[$row][0]=$oid;
				$index=1;
				foreach($rows[0] as $col)
					$tmp[$row][$index++]=$col;
				$row++;
			}
			$ret[$tid]=$this->sort($sort,$tmp,$rowlimit);
		}
		return $ret;
	}
		
	function sort($sortcol,$data,$rowlimit,$desc=true) {
		if(!$sortcol)
			return $data;
		$sdata=array();
		foreach($data as $index=>$d)
			$sdata["$index"]=$d[$sortcol];
		$ret=array();
		asort($sdata);
		if($desc)
			$sdata=array_reverse($sdata,true);
		$c=0;
		foreach($sdata as $index=>$d) {
			$ret[]=$data[$index];
			if($rowlimit>0 and $c++==$rowlimit)
				break;
		}
		return $ret;
	}

	function getReportInfo($dom,$source)
	//Return: string containing xml template definition 
	{
		if(($str=file_get_contents(dirname(__FILE__)."/".get_class($this)."/".get_class($this).".xml"))==FALSE)
			throw new Exception("Could not read xml template: ".dirname(__FILE__)."/".get_class($this)."/".get_class($this).".xml\n");
		return $str;
	}
	
	function getFirstLastTP($timeperiods) {
		$first=$last=array_pop($timeperiods);
		foreach($timeperiods as $tp) { 
			if($tp>$last)
				$last=$tp;
 			if($tp<$first)
				$first=$tp;
		}
		return array('first'=>$first,'last'=>$last);
	}
	
	function initDOM($index,$dom,$xp) {
		$this->dom=$dom;
		$this->xp=$xp;
		$this->index=$index;
		$ma=$this->dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","ma");
		$ma->appendChild($this->dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","id",$index));
		$ma->appendChild($this->dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","name",$this->getName()));
		$ma->appendChild($this->initDatasources($this->dom));
		return $ma;		
	}

	function initObspoints($dom,$source) {
		$xmlstr='<obsPoints xmlns="http://stager.uninett.no/perfsonarnc/1.0">';
		foreach($this->getObspoints($source) as $o) {
			$xmlstr.="<obsPoint><id>".$o['id']."</id><name>".$o['name']."</name>";
			if(isset($o['direction']))
				$xmlstr.="<direction>".$o['direction']."</direction>";
			if(isset($o['sampling']))
			$xmlstr.="<sampling>".$o['sampling']."</sampling>";
			if(isset($o['capacity']))
			$xmlstr.="<capacity>".$o['capacity']."</capacity>";
			if(isset($o['hostname']))
			$xmlstr.="<hostname>".$o['hostname']."</hostname>";
			$xmlstr.="<ipaddress>".$o['ip']."</ipaddress>";
			$xmlstr.="</obsPoint>";
		}
		$xmlstr.="</obsPoints>";
		$d=new domdocument();
		$d->loadXML($xmlstr);						
		return $dom->importNode($d->firstChild,true);			
	}

	function initTimeInfo($dom,$source) {
	  $time=$dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","timeInfo");
	  $this->timeinfo[$source]=$this->getTimeinfo($source);
	  if(is_array($this->timeinfo[$source])) {
	    foreach($this->timeinfo[$source] as $t) {
	      $i=$dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","resolution");
	      $time->appendChild($i);
	      $i->appendChild($dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","duration", $t['duration']));
	      $i->appendChild($dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","name", $t['name']));
	      if(strlen($t['plot_from'])>0)
		$i->appendChild($dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","plotFrom", $t['plot_from']));
	      $i->appendChild($dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","first", $t['first']));
	      $i->appendChild($dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","last", $t['last']));
	    }
	  }
	  return $time;
	}
	
	function rpcError($type,$msg,$severity="error") {
		$this->error=array(
		       'error-type'=>$type,
		       'error-tag'=>'',
		       'error-severity'=>$severity,
		       'error-message'=>$msg
		);
	}

	function initDatasources($dom) {
		$ds=$dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","dataSources");
		foreach($this->getDatasources() as $id=>$name) {
			$s=$dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","dataSource");
			$ds->appendChild($s);
			$s->appendChild($dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","id",$id));
			$s->appendChild($dom->createElementNS("http://stager.uninett.no/perfsonarnc/1.0","name",$name));
			$s->appendChild($this->initObspoints($dom,$id));
			if($node=$this->initTimeInfo($dom,$id))
				$s->appendChild($node);
			if($node=$this->initReportInfo($dom,$id))
				$s->appendChild($node);
		}
		return $ds;
	}

	function initReportInfo($dom,$id) {
		$str=$this->getReportInfo($dom,$id);
		$d=new domdocument();
		$d->loadXML($str);
		return $this->dom->importNode($d->firstChild,true);
	}


	abstract function getTableOrSingleData($source,$tid,$report,$obs,$type,$view,$filter,$sort,$rowlimit,$arguments);
	abstract function getObspoints($source);
	abstract function getTimeInfo($source);
	abstract function getName();
	abstract function getDatasources();
}
?>
